package org.hydrakyoufeng.qiniu;

import java.io.File;
import java.util.Base64;
import java.util.Map;

import org.hydrakyoufeng.base.tool.collection.MT;
import org.hydrakyoufeng.base.tool.collection.MU;
import org.hydrakyoufeng.base.tool.json.JsonReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.DownloadUrl;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;

@Repository
public class QiniuRepository {
	
	private final QiniuConfig.QiniuProperties qiniuProperties;

	private final QiniuConfig.QiniuProperties qiniuSecretProperties;
	
	private final JsonReader jsonReader;
	
	/**
	 * 七牛云配置
	 */
	private final Configuration cfg;
	
	
	/**
	 * 公开空间token的失效时间
	 */
	private long deadline = 0;

	/**
	 * 公开空间的token
	 */
	private String token;

	/**
	 * 私有空间token的失效时间
	 */
	private long deadlineSecret = 0;

	/**
	 * 私有空间的token
	 */
	private String tokenSecret;
	

	@Autowired
	public QiniuRepository(@Qualifier("qiniuProperties") QiniuConfig.QiniuProperties qiniuProperties,
			@Qualifier("qiniuSecretProperties") QiniuConfig.QiniuProperties qiniuSecretProperties,
			JsonReader jsonReader) {
		this.qiniuProperties = qiniuProperties;
		this.qiniuSecretProperties = qiniuSecretProperties;
		this.jsonReader = jsonReader;
		cfg = new Configuration(Region.region2());
		// 指定分片上传版本
		cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;
	}

	public Map<String, Object> getToken() throws Exception {
		Auth auth = Auth.create(qiniuProperties.getAccessKey(), qiniuProperties.getSecretKey());
		// 在失效时间之前，都是用原来的token，避免重复获取token
		if (deadline * 1000 - System.currentTimeMillis() <= 60 * 1000) {
			token = auth.uploadToken(qiniuProperties.getBucket());
			int index = token.lastIndexOf(':');
			String tokenBuffer = new String(Base64.getMimeDecoder().decode(token.substring(index + 1)));
			Map<?, ?> map = jsonReader.get(tokenBuffer);
			deadline = MT.getLong(map, "deadline",0);
		}
		var data = MU.pop();
		data.put("token", token);
		data.put("remoteAddr", qiniuProperties.getRemoteAddr());
		return data;
	}
	
	public Map<String, Object> getTokenSecret() throws Exception {
		Auth auth = Auth.create(qiniuSecretProperties.getAccessKey(), qiniuSecretProperties.getSecretKey());
		// 在失效时间之前，都是用原来的token，避免重复获取token
		if (deadlineSecret * 1000 - System.currentTimeMillis() <= 60 * 1000) {
			tokenSecret = auth.uploadToken(qiniuSecretProperties.getBucket());
			int index = tokenSecret.lastIndexOf(':');
			String tokenBuffer = new String(Base64.getMimeDecoder().decode(tokenSecret.substring(index + 1)));
			Map<?, ?> map = jsonReader.get(tokenBuffer);
			deadlineSecret = MT.getLong(map, "deadline",0);
		}
		var data = MU.pop();
		data.put("token", token);
		data.put("remoteAddr", qiniuSecretProperties.getRemoteAddr());
		return data;
	}
	
	public String getSourceURL(Map<String,Object> param) throws Exception {
		// 获取域名：将配置的域名去掉https://
		String domain = qiniuSecretProperties.getRemoteAddr().replace("https://", "");
		DownloadUrl url = new DownloadUrl(domain, true, MT.getString(param,"key"));
		// 设置过期时间，单位：秒，1小时，可以自定义链接过期时间
		Integer expireInSeconds = qiniuSecretProperties.getExpire();
		long deadline = System.currentTimeMillis() / 1000 + expireInSeconds;
		Auth auth = Auth.create(qiniuSecretProperties.getAccessKey(), qiniuSecretProperties.getSecretKey());
		return url.buildURL(auth, deadline);
	}
	
	/**
	 * 上传文件
	 * @param content
	 * @param key
	 * @param token
	 * @return
	 * @throws Exception
	 */
	public Map<String,Object> upload(File file,String key,String token) throws Exception {
		UploadManager uploadManager = new UploadManager(cfg);
		Response response = uploadManager.put(file, key, token);
		return jsonReader.get(response.bodyString());
	}

}
